package com.asman.vr

import android.app.Activity
import android.content.Context
import android.content.DialogInterface
import android.graphics.BitmapFactory
import android.util.AttributeSet
import android.util.Base64
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.TextView
import com.alibaba.android.arouter.facade.annotation.Autowired
import com.asman.base.lib.utils.StatusBarUtil
import com.asman.im_trtc.TRTCCloudCallBack
import com.asman.im_trtc.TRTCEnterResultCallBack
import com.asman.im_trtc.TRTCUtils
import com.asman.vr.network.TrtcAuthInfoData
import com.asman.vr.utils.EventBusUtils
import com.asman.vr.utils.EventData
import com.asman.vr.utils.UrlUtils
import com.asman.vr.utils.WXSdk
import com.google.gson.Gson
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage
import com.tencent.mm.opensdk.modelmsg.WXMiniProgramObject
import com.tencent.trtc.TRTCCloudListener
import io.flutter.plugin.common.MethodChannel
import io.reactivex.disposables.Disposable
import log
import org.greenrobot.eventbus.Subscribe
import ossZip
import parseIntOrNull
import showToast
import java.net.URLEncoder


class VRWebView : RelativeLayout {

//    var activity: Activity? = null
    var methodChannel: MethodChannel? = null
    var tenantId: String? = null
    var shareBaseUrl: String? = null

    var audioPermissionCallback: AudioPermissionCallbackInterface? = null

    var wxSdk: WXSdk = WXSdk()

    // todo 这里有用构造函数传入 url
    // @JvmField
    // @Autowired(required = true, desc = "地址链接 http/s")
    // var url: String? = null
    var url: String? = ""

    @JvmField
    @Autowired(required = false, desc = "title 默认标题")
    var title: String? = null

    // @JvmField
    // @Autowired(required = false, desc = "隐藏标题栏")
    // var hiddenTitle: Boolean = false
    var hiddenTitle: Boolean = true

    // @JvmField
    // @Autowired(required = false, desc = "全屏显示--影藏状态栏")
    var fullScreen: Boolean = true

    // @JvmField
    // @Autowired(required = false, desc = "是否来自接听动作")
    var isFromReceive: Boolean = false

    internal var content: String? = null

    private var titles: MutableList<String> = ArrayList()
    
    private lateinit var model: BaseWebViewModel

    //录音组件
    private var recorderUtil: RecorderUtil? = null

    //url携带的参数map
    var urlParamMap: Map<String, String>? = null

    // todo 这里重载了 activity 的方法
    /*override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        url = intent?.getStringExtra("url")
        if (url.isNullOrEmpty()) {
            showToast("地址不存在")
            return
        }
        title = intent?.getStringExtra("title")
        hiddenTitle = intent?.getBooleanExtra("hiddenTitle", false) ?: false
        fullScreen = intent?.getBooleanExtra("fullScreen", false) ?: false
        isFromReceive = intent?.getBooleanExtra("isFromReceive", false) ?: false
        initView()
        loadUrl()
        urlParamMap = UrlUtils.formatUrl2Map(url)
        if (isFromReceive) {
            autoJoinRoom()
        }
    }*/

    //设计师自己是否加入成功
    var autoEnterSuccess: Boolean? = null

    // 加入房间 给 flutter 调用
    fun joinRoom(trtcAuthInfoData: TrtcAuthInfoData) {
        trtcUtils = TRTCUtils()
        trtcUtils!!.init(
                context,
                sdkAppId = (trtcAuthInfoData.sdkAppId) ?: 0,
                userId = trtcAuthInfoData.userId ?: "",
                roomId = urlParamMap?.get("roomId").parseIntOrNull()
                        ?: 0,
                userSig = trtcAuthInfoData.userSig ?: "",
                callBack = object : TRTCCloudCallBack {
                    override fun onRemoteUserEnterRoom(userId: String) {
                        log("joinRoom---autoJoinRoom-onRemoteUserEnterRoom")
                        clientUserId = userId
                        hasLeave = false
                        val data = NotifyTrtcH5(
                                type = NotifyTrtcH5.NotifyTrtcH5Type.onRemoteUserEnterRoom.name,
                                params = NotifyTrtcH5.UserEnterRoom(
                                        userId
                                )
                        )
                        webView?.notifyTrtcH5(data)
                    }

                    override fun onRemoteUserLeaveRoom(userId: String, reason: Int) {
                        log("joinRoom---autoJoinRoom-onRemoteUserLeaveRoom")
                        hasLeave = true
                        log("===有人离开了：${userId}---$reason")
                        val data = NotifyTrtcH5(
                                type = NotifyTrtcH5.NotifyTrtcH5Type.onRemoteUserLeaveRoom.name,
                                params = NotifyTrtcH5.UserLeaveRoom(
                                        userId, reason
                                )
                        )
                        webView?.notifyTrtcH5(data)
                    }

                    override fun onError(msg: String) {
                        super.onError(msg)
                        log("joinRoom---autoJoinRoom-onError-${msg}")
                    }

                    //断连恢复之后再调一遍onRemoteUserEnterRoom，否则全景那边会有些问题
                    override fun onConnectionRecovery() {
                        super.onConnectionRecovery()
                        if (hasLeave == false) {
                            val data = NotifyTrtcH5(
                                    type = NotifyTrtcH5.NotifyTrtcH5Type.onRemoteUserEnterRoom.name,
                                    params = NotifyTrtcH5.UserEnterRoom(clientUserId ?: "")
                            )
                            webView?.notifyTrtcH5(data)
                        } else {
                            val data = NotifyTrtcH5(
                                    type = NotifyTrtcH5.NotifyTrtcH5Type.onRemoteUserLeaveRoom.name,
                                    params = NotifyTrtcH5.UserEnterRoom(clientUserId ?: "")
                            )
                            webView?.notifyTrtcH5(data)
                        }
                    }
                })

        // todo 调用 flutter 层的获取麦克风操作-done
        audioPermissionCallback = object: AudioPermissionCallbackInterface {
            override fun requestAudioSuccessCb(){
                trtcUtils?.enterRoom(
                        object : TRTCEnterResultCallBack {
                            override fun onEnterRoomSuccess(result: Long) {
                                log("joinRoom---autoJoinRoom-startEnterRoomSuccess")
                                // todo 这部分掉结构放到 flutter 中做 -done
                                methodChannel!!.invokeMethod("notifyDesignerJoined", "")
                                /*//加入房间成功调接口告诉后端设计师已接听
                                model.hasReceived(
                                        roomId = trtcUtils?.roomId,
                                        schemeId = urlParamMap?.get("schemeId")
                                                .parseLongOrNull(),
                                        vrType = urlParamMap?.get("vrType")
                                                .parseIntOrNull()
                                )*/
                                autoEnterSuccess = true
                                log("joinRoom---autoJoinRoom-onEnterRoomSuccess")
                            }

                            override fun onEnterRoomError(result: Long) {
                                autoEnterSuccess = false
                                log("joinRoom---autoJoinRoom-onEnterRoomError--$result")
                            }
                        })
            }
            override fun requestAudioFailCb(){
                autoEnterSuccess = false
                log("joinRoom---autoJoinRoom-onEnterRoomError")
            }
        }
        methodChannel!!.invokeMethod("requestAudioPermission", "requestAudioSuccessCb,requestAudioFailCb")
        /*PermissionUtils.requestAudio(
                // this@VRWebActivity,
                context as FragmentActivity,
                object : PermissionUtils.OnPermissionListener() {
                    override fun success() {
                        trtcUtils?.enterRoom(
                                object : TRTCEnterResultCallBack {
                                    override fun onEnterRoomSuccess(result: Long) {
                                        //加入房间成功调接口告诉后端设计师已接听
                                        model.hasReceived(
                                                roomId = trtcUtils?.roomId,
                                                schemeId = urlParamMap?.get("schemeId")
                                                        .parseLongOrNull(),
                                                vrType = urlParamMap?.get("vrType")
                                                        .parseIntOrNull()
                                        )
                                        autoEnterSuccess = true
                                        log("joinRoom---autoJoinRoom-onEnterRoomSuccess")
                                    }

                                    override fun onEnterRoomError(result: Long) {
                                        autoEnterSuccess = false
                                        log("joinRoom---autoJoinRoom-onEnterRoomError--$result")
                                    }
                                })
                    }

                })*/
    }

    //自动加入房间
    private fun autoJoinRoom() {
        // todo 整个方法改成调 flutter 层 -done
        methodChannel!!.invokeMethod("getTrtcAuthInfo", "")
        //获取腾讯appKey等信息
        /*model.getTrtcAuthInfo(
                schemeId = urlParamMap?.get("schemeId")
                        .parseLongOrNull(),
                vrType = urlParamMap?.get("vrType")
                        .parseIntOrNull()
                // todo 这里用 context 强转成 LifecycleOwner 不知道对不对
                // ).observe(this, Observer {
        ).observe(context as LifecycleOwner, Observer {
            when (it.status) {
                Status.LOADING -> {
                    log("joinRoom---autoJoinRoom-LOADING")

                    // todo BaseActivity 的方法
                    // showDialogProgress("正在获取配置信息")
                }
                Status.SUCCESS -> {
                    log("joinRoom---autoJoinRoom-SUCCESS")

                    // todo BaseActivity 的方法
                    // dismissDialog()

                    //加入房间
                    trtcUtils = TRTCUtils()
                    trtcUtils!!.init(
                            // todo 这里直接把 this 改成了 context 不知道对不对
                            // this, sdkAppId = it.data?.sdkAppId.parseIntOrNull()
                            context, sdkAppId = it.data?.sdkAppId.parseIntOrNull()
                            ?: 0,
                            userId = it.data?.userId ?: "",
                            roomId = urlParamMap?.get("roomId").parseIntOrNull()
                                    ?: 0,
                            userSig = it.data?.userSig ?: "",
                            callBack = object : TRTCCloudCallBack {
                                override fun onRemoteUserEnterRoom(userId: String) {
                                    log("joinRoom---autoJoinRoom-onRemoteUserEnterRoom")
                                    clientUserId = userId
                                    hasLeave = false
                                    val data = NotifyTrtcH5(
                                            type = NotifyTrtcH5.NotifyTrtcH5Type.onRemoteUserEnterRoom.name,
                                            params = NotifyTrtcH5.UserEnterRoom(
                                                    userId
                                            )
                                    )
                                    webView?.notifyTrtcH5(data)
                                }

                                override fun onRemoteUserLeaveRoom(userId: String, reason: Int) {
                                    log("joinRoom---autoJoinRoom-onRemoteUserLeaveRoom")
                                    hasLeave = true
                                    log("===有人离开了：${userId}---$reason")
                                    val data = NotifyTrtcH5(
                                            type = NotifyTrtcH5.NotifyTrtcH5Type.onRemoteUserLeaveRoom.name,
                                            params = NotifyTrtcH5.UserLeaveRoom(
                                                    userId, reason
                                            )
                                    )
                                    webView?.notifyTrtcH5(data)
                                }

                                override fun onError(msg: String) {
                                    super.onError(msg)
                                    log("joinRoom---autoJoinRoom-onError-${msg}")
                                }

                                //断连恢复之后再调一遍onRemoteUserEnterRoom，否则全景那边会有些问题
                                override fun onConnectionRecovery() {
                                    super.onConnectionRecovery()
                                    if (hasLeave == false) {
                                        val data = NotifyTrtcH5(
                                                type = NotifyTrtcH5.NotifyTrtcH5Type.onRemoteUserEnterRoom.name,
                                                params = NotifyTrtcH5.UserEnterRoom(clientUserId ?: "")
                                        )
                                        webView?.notifyTrtcH5(data)
                                    } else {
                                        val data = NotifyTrtcH5(
                                                type = NotifyTrtcH5.NotifyTrtcH5Type.onRemoteUserLeaveRoom.name,
                                                params = NotifyTrtcH5.UserEnterRoom(clientUserId ?: "")
                                        )
                                        webView?.notifyTrtcH5(data)
                                    }
                                }
                            })

                    // todo 这里第一个参数需要传 activity，把 context 强转成 FragmentActivity，强转失败，把获取权限放到 flutter 中去做
                    PermissionUtils.requestAudio(
                            // this@VRWebActivity,
                            context as FragmentActivity,
                            object : PermissionUtils.OnPermissionListener() {
                                override fun success() {
                                    trtcUtils?.enterRoom(
                                            object : TRTCEnterResultCallBack {
                                                override fun onEnterRoomSuccess(result: Long) {
                                                    //加入房间成功调接口告诉后端设计师已接听
                                                    model.hasReceived(
                                                            roomId = trtcUtils?.roomId,
                                                            schemeId = urlParamMap?.get("schemeId")
                                                                    .parseLongOrNull(),
                                                            vrType = urlParamMap?.get("vrType")
                                                                    .parseIntOrNull()
                                                    )
                                                    autoEnterSuccess = true
                                                    log("joinRoom---autoJoinRoom-onEnterRoomSuccess")
                                                }

                                                override fun onEnterRoomError(result: Long) {
                                                    autoEnterSuccess = false
                                                    log("joinRoom---autoJoinRoom-onEnterRoomError--$result")
                                                }
                                            })
                                }

                            })
                }
                else -> {
                    dismissDialog()
                    showToast("获取配置信息失败")
                }
            }
        })*/
    }
    
    // todo onCreate 生命周期的内容，放到构造函数里面 -done
    /*override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_base_web)
        EventBusUtils.register(this)
        RouterUtils.inject(this)

        if (url.isNullOrEmpty()) {
            showToast("地址不存在")
            return
        }
        ivBack.setOnClickListener { onBackPressed() }
        ivClose.setOnClickListener { finish() }
        model = ViewModelProviders.of(this, object : ViewModelProvider.Factory {
            override fun <T : ViewModel?> create(modelClass: Class<T>): T {
                val repo =
                        let { ServiceLocator.instance(this@VRWebActivity).getAccountRepository() }
                val repo1 =
                        let { ServiceLocator.instance(this@VRWebActivity).getBaseDataRepository() }
                val repo2 =
                        let { ServiceLocator.instance(this@VRWebActivity).getCallAnswerRepository() }
                return BaseWebViewModel(this@VRWebActivity, repo, repo1, repo2) as T
            }
        })[BaseWebViewModel::class.java]
        initView()
        initWebView()
        loadUrl()
        urlParamMap = UrlUtils.formatUrl2Map(url)
        if (isFromReceive) {
            autoJoinRoom()
        }
    }*/

    constructor(
            context: Context, url: String, methodChannel: MethodChannel,
            hiddenTitle: Boolean, fullScreen: Boolean, isFromReceive: Boolean, tenantId: String, shareBaseUrl: String
    ) : this(
            context, url, methodChannel,
            hiddenTitle, fullScreen, isFromReceive, tenantId, shareBaseUrl,
            null, 0
    )
    
    constructor(
            context: Context, url: String, methodChannel: MethodChannel,
            hiddenTitle: Boolean, fullScreen: Boolean, isFromReceive: Boolean, tenantId: String, shareBaseUrl: String,
            attrs: AttributeSet
    ) : this(
            context, url, methodChannel,
            hiddenTitle, fullScreen, isFromReceive, tenantId, shareBaseUrl,
            attrs, 0
    )
    
    constructor(
            context: Context, url: String, methodChannel: MethodChannel,
            hiddenTitle: Boolean, fullScreen: Boolean, isFromReceive: Boolean, tenantId: String, shareBaseUrl: String,
            attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
//        this.activity = activity
        this.methodChannel = methodChannel
        this.url = url
        if (hiddenTitle != null) this.hiddenTitle = hiddenTitle
        if (fullScreen != null) this.fullScreen = fullScreen
        if (isFromReceive != null) this.isFromReceive = isFromReceive

        this.tenantId = tenantId
        this.shareBaseUrl = shareBaseUrl

        // 初始化微信 sdk
        wxSdk.regToWx(context);

        LayoutInflater.from(context).inflate(R.layout.my_view, this, true)
        webView = findViewById(R.id.webView)
        // todo 下面是原来 activity 中 onCreate 生命周期的内容，不知道对不对
        EventBusUtils.register(this)
        
        // todo 下面的 Router 先直接拿掉了
        // RouterUtils.inject(this)

        if (url.isNullOrEmpty()) {
            showToast("地址不存在")
            return
        }

        // ivBack.setOnClickListener { onBackPressed() }
        findViewById<ImageView>(R.id.ivBack).setOnClickListener { onBackPressed() }
        
        // ivClose.setOnClickListener { finish() }
        findViewById<ImageView>(R.id.ivClose).setOnClickListener{ finish("") }

        // todo context 强转 FragmentActivity 报错
        // model = ViewModelProviders.of(this, object : ViewModelProvider.Factory {
        /*model = ViewModelProviders.of(context as FragmentActivity, object : ViewModelProvider.Factory {
            override fun <T : ViewModel?> create(modelClass: Class<T>): T {
                
                // todo this@VRWebActivity 强制变为 context as Activity
                
                val repo =
                        // let { ServiceLocator.instance(this@VRWebActivity).getAccountRepository() }
                         let { ServiceLocator.instance(context as Activity).getAccountRepository() }
                val repo1 =
                        // let { ServiceLocator.instance(this@VRWebActivity).getBaseDataRepository() }
                         let { ServiceLocator.instance(context as Activity).getBaseDataRepository() }
                val repo2 =
                        // let { ServiceLocator.instance(this@VRWebActivity).getCallAnswerRepository() }
                         let { ServiceLocator.instance(context as Activity).getCallAnswerRepository() }
                // return BaseWebViewModel(this@VRWebActivity, repo, repo1, repo2) as T
                return BaseWebViewModel(context as LifecycleOwner, repo, repo1, repo2) as T
            }
        })[BaseWebViewModel::class.java]*/
        initView()
        initWebView()
        loadUrl()
        urlParamMap = UrlUtils.formatUrl2Map(url)

        Log.d("vrwebview", this.isFromReceive.toString())
        
        if (isFromReceive) {
            autoJoinRoom()
        }

        hiddenBottomButton()
    }

    private fun initView() {
        if (hiddenTitle) {
            // layout_title.visibility = View.GONE
            findViewById<LinearLayout>(R.id.layout_title).visibility = View.GONE
        } else {
            // layout_title.visibility = View.VISIBLE
            findViewById<LinearLayout>(R.id.layout_title).visibility = View.VISIBLE
        }
        if (fullScreen) {
            /*// todo this 用 activity 代替 -done
            // StatusBarUtil.setTranslucentForImageView(this, 0, null)
            StatusBarUtil.setTranslucentForImageView(activity, 0, null)

            // todo this 用 activity 代替 -done
            activity?.let { KeyBoardListener.getInstance(it).init1() }*/
        }
    }

    var downloadShareImage: Disposable? = null

    // 分享到微信 - 图片
    fun shoreToWX(base64Data: String) {
        var bytes = Base64.decode(base64Data, Base64.DEFAULT)
        var bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
        if (bmp != null) {
            wxSdk.shareImg(bmp)
        }
    }

    // 分享到微信 - 小程序
    fun shareToWXMin() {

    }


    private fun initWebView() {

        Log.d("initWebView", "initWebView")

        // todo 暂时还没有 BuildConfig，先写死 1.2.8
        //这段代码必须加上---和js交互的约定
        // webView?.setAppVersionName(BuildConfig.VERSION_NAME)
        webView?.setAppVersionName("1.2.8")

        //currentStep  1
        webView?.setOnJSBridgeCallBackListener(object : OnJSBridgeCallBack {

            // todo 页面跳转直接换成调用 flutter 方法
            /*override fun jump2NativePage(uri: String) = IntentUtils.intentARouter(
                this@VRWebActivity,
                uri
            )*/
            override fun jump2NativePage(uri: String) {
                Log.d("OnJSBridgeCallBack", "jump2NativePage")
                Log.d("OnJSBridgeCallBack", uri)
            }

            override fun showShareView() {
                Log.d("OnJSBridgeCallBack", "showShareView")
                webView?.getH5ShareParams {
                    if (it != null) {
                        // todo 显示分享页面
                        /*IntentUtils.intentShare(
                                this@VRWebActivity,
                                it.shareTitle ?: "",
                                it.shareDesc ?: "",
                                it.shareLink ?: ""
                        )*/
                        print("显示分享页面")
                    }
                }
            }

            override fun shareWXMiniProgram(shareMiniProgramInfo: ShareMiniProgramInfo) {
                Log.d("OnJSBridgeCallBack", "shareWXMiniProgram")

                methodChannel!!.invokeMethod("checkMini", null, object : MethodChannel.Result{
                    override fun notImplemented() {
                        TODO("Not yet implemented")
                    }

                    override fun error(errorCode: String?, errorMessage: String?, errorDetails: Any?) {
                        TODO("Not yet implemented")
                    }

                    override fun success(result: Any?) {
                        Log.d("--- share result ---", result?.toString())
                        if (result == true) {

                            /*// todo 缺少兜底连接
                            val webpageUrl = "http://www.eastlanco.com/";

                            val params =
                                    "?" + shareMiniProgramInfo.shareLink?.substringAfterLast("?")
                            val path =
                                    "/pages/3DRoam/3DRoam?shareUrl=${URLEncoder.encode(
                                            params,
                                            "UTF-8"
                                    )}"

                            var thumbData: ByteArray?
                            if (shareMiniProgramInfo.shareImage == null) {
                                showToast("分享图片不能为空")
                                return
                            }
                            thumbData = DownloadImg.getImgBytes(shareMiniProgramInfo.shareImage.ossZip(375f, 300f, 2f))
                            var title = shareMiniProgramInfo.shareTitle
                                    ?: "东方莱可"
                            var description = shareMiniProgramInfo.shareDesc
                                    ?: "东方莱可"

                            wxSdk.shareToWXMin(webpageUrl, path, thumbData, title, description)*/

                            val schemeId = shareMiniProgramInfo.schemeId

                            var img = shareMiniProgramInfo.shareImage
                            var title = shareMiniProgramInfo.shareTitle
                            var price = shareMiniProgramInfo.shareDesc
                            var shareUrl = "${shareBaseUrl}?tenantId=${tenantId}&schemeId=${schemeId}"

                            var arguments = HashMap<String, String>()
                            if (img == null) {
                                arguments.set("img", "")
                            } else {
                                arguments.set("img", img)
                            }
                            if (title == null) {
                                arguments.set("title", "")
                            } else {
                                arguments.set("title", title)
                            }
                            if (price == null) {
                                arguments.set("price", "")
                            } else {
                                arguments.set("price", price)
                            }
                            if (shareUrl == null) {
                                arguments.set("shareUrl", "")
                            } else {
                                arguments.set("shareUrl", shareUrl)
                            }

                            methodChannel!!.invokeMethod("generateShareWidget", arguments)
                        }
                    }
                })

                // todo 微信分享 -done
                /*val schemeId = shareMiniProgramInfo.schemeId
                val url = "${shareBaseUrl}?schemeId=${schemeId}&tenantId=${tenantId}"
                val bmp = QRCodeUtil.createQRCodeBitmap(url, 480, 480)
                if (bmp != null) {
                    wxSdk.shareImg(bmp)
                }*/
                /*if (!MyApplication.context.resources.getBoolean(R.bool.config_wx_share_mini_open)) {
                    showToast("暂未开通此功能")
                    return
                }
                //事件埋点
                UmengUtils.onEventObject(
                        this@VRWebActivity, UMEventKey.rendering_share.product_from.id,
                        mapOf(
                                UMEventKey.rendering_share.product_from.key to UMEventKey.rendering_share.product_from.value,
                                UMEventKey.rendering_share.rendering_id.key to shareMiniProgramInfo.schemeId,
                                UMEventKey.rendering_share.share_rendering.key to UMEventKey.rendering_share.share_rendering.value
                        )
                )*/

                /*downloadShareImage =
                        Observable.just(shareMiniProgramInfo.shareImage.ossZip(375f, 300f, 2f))
                                .subscribeOn(Schedulers.io())
                                .map {
                                    GlideApp.with(this@VRWebActivity).asBitmap().load(it).submit().get()
                                }
                                .map { BitmapUtils.bitmap2Byte(it, maxKB) }
                                .observeOn(AndroidSchedulers.mainThread())
                                .subscribe {
                                    thumbData = it
                                    //分享小程序3D换搭的地址和参数---开始必须是 问号，
                                    val params =
                                            "?" + shareMiniProgramInfo.shareLink?.substringAfterLast("?")
                                    val path =
                                            "/pages/3DRoam/3DRoam?shareUrl=${URLEncoder.encode(
                                                    params,
                                                    "UTF-8"
                                            )}"
                                    WXEntryActivity.shareXCX(
                                            path,
                                            shareMiniProgramInfo.shareTitle
                                                    ?: getString(R.string.config_app_name),
                                            shareMiniProgramInfo.shareDesc
                                                    ?: getString(R.string.config_app_name),
                                            thumbData!!
                                    )
                                    dismissDialog()
                                    downloadShareImage?.dispose()
                                }*/
            }

            override fun getUserInfo(callBack: ((userInfo: UserInfoRes) -> Unit)?) {

                Log.d("OnJSBridgeCallBack", "getUserInfo")

                // todo 登陆 没有登录需要登录-done 全景页不掉这个方法了
                // 没有登录需要跳转登陆
                /*if (sp.getString(SP_LOGIN_TOKEN, "").isNullOrEmpty()) {
                    startActivity(Intent(this@VRWebActivity, LoginChoiceActivity::class.java))
                    callBack?.invoke(UserInfoRes(null, null, null, null))
                } else {
                    model.getUserInfo().observe(this@VRWebActivity, Observer {
                        when (it.status) {
                            Status.LOADING -> {
                            }
                            Status.SUCCESS -> {
                                //获取用户信息，实时获取，保证给到js的token是有效的
                                spSaveUserInfo(it.data)
                                //用户信息接口不会返回token
                                callBack?.invoke(
                                        UserInfoRes(
                                                it.data?.userName,
                                                it.data?.mobile,
                                                it.data?.loginInfo?.token,
                                                it.data?.userId
                                        )
                                )
                            }
                            else -> callBack?.invoke(UserInfoRes(null, null, null))
                        }
                    })
                }*/
                print("getUserInfo 或跳转登陆页")
            }

            override fun topNavigationBar(isHidden: Int) {
                Log.d("OnJSBridgeCallBack", "topNavigationBar")
                if (isHidden == 1) {
                    // layout_title.visibility = View.GONE
                    findViewById<LinearLayout>(R.id.layout_title).visibility = View.GONE
                } else if (isHidden == 0) {
                    // layout_title.visibility = View.VISIBLE
                    findViewById<LinearLayout>(R.id.layout_title).visibility = View.VISIBLE
                }
            }

            // todo 直接调 onBackPressed
            // override fun goBack() = this@VRWebActivity.onBackPressed()
            override fun goBack() = onBackPressed()

            override fun closeNativeView() = onBackPressed()

            override fun switchToDesignerShopView(designer: DesignerDetailParam) {
                Log.d("OnJSBridgeCallBack", "switchToDesignerShopView")
                // todo 友盟埋点
                //事件埋点
                /*UmengUtils.addEvent(
                        this@VRWebActivity, UMEventKey.enter_designer_shop.from_Rendering.id, mapOf(
                        UMEventKey.enter_designer_shop.from_Rendering.key to UMEventKey.enter_designer_shop.from_Rendering.value
                )
                )*/

                // todo 页面跳转 -done
                //跳转设计师主页
                // DesignerDetailActivity.startActivity(this@VRWebActivity, designer.designerId ?: 0)
                methodChannel!!.invokeMethod("switchToDesignerShopView", designer.designerId)
            }

            override fun switchToQuotationView(decorationInfo: DecorateDetailParam) {
                Log.d("OnJSBridgeCallBack", "switchToQuotationView")

                // todo 跳转报价单页面 - done
                var decorationInfoJsonStr: String = Gson().toJson(decorationInfo)
                methodChannel!!.invokeMethod("routeToDecorateDetail", decorationInfoJsonStr)
                //跳转报价单页面
                /*DecorateDetailActivity.startActivity(
                        this@VRWebActivity,
                        decorationInfo.schemeId,
                        decorationInfo.workId,
                        Gson().toJson(decorationInfo.hotspots)
                )*/
            }

            override fun showLoginView(): UserInfoRes {
                Log.d("OnJSBridgeCallBack", "showLoginView")

                return UserInfoRes()//跳转登陆页面--app是强制登陆--所有不需要
            }

            override fun showSharePageView(info: SharePageViewParam) {
                Log.d("OnJSBridgeCallBack", "showSharePageView")
                // todo 显示分享页
                /*if (resources.getBoolean(R.bool.config_wx_share_mini_open)) {
                    ShareActivity.startActivity(this@VRWebActivity, info)
                } else {
                    showToast("暂未开通此功能")
                }*/
                print("显示分享页")
            }

            override fun showGoodsDetailView(info: GoodsDetailParam) {
                Log.d("OnJSBridgeCallBack", "showGoodsDetailView")
                // todo 跳转 GoodsDetailActivity
                // GoodsDetailActivity.startActivity(this@VRWebActivity, info.skuId ?: 0)
                print("跳转 GoodsDetailActivity")
            }

            override fun recordBegin(callBack: (() -> Unit)?) {
                Log.d("OnJSBridgeCallBack", "recordBegin")
                log("===recordBegin")
                //获取权限
                /*PermissionUtils.requestAudio(
                        // todo 用 context as Activity 换 this@VRWebActivity
                        // this@VRWebActivity,
                        context as FragmentActivity,
                        object : PermissionUtils.OnPermissionListener() {
                            override fun success() {
                                onStartAudioRecord()
                                //告诉js开始录音了
                                callBack?.invoke()
                            }
                        })*/
            }

            override fun getRecord(callBack: (base64: String?, isSuccess: Boolean?) -> Unit) {
                Log.d("OnJSBridgeCallBack", "getRecord")
                log("===getRecord")
                recordCompletedCallBack = callBack
                onEndAudioRecord()
            }

            override fun stopRecord() {
                Log.d("OnJSBridgeCallBack", "stopRecord")
                cancelRecord()
            }

            override fun saveLocalParamData(key: String, value: String) {
                Log.d("OnJSBridgeCallBack", "saveLocalParamData")
                // todo sp
                /*sp.edit {
                    putString(key, value)
                }*/
            }

            // todo sp
            // override fun getLocalParamData(key: String): String? = sp.getString(key, "")
            override fun getLocalParamData(key: String): String? = ""

            // todo context
            override fun getStatusBarHeight() =
                    // StatusBarUtil.getStatusBarHeight(this@VRWebActivity)
                    StatusBarUtil.getStatusBarHeight(context)

            override fun callAppTrtc(
                    info: CallAppTrtc,
                    callBack: (resp: BaseJSBridgeDataT<Boolean>) -> Unit
            ) {

                Log.d("OnJSBridgeCallBack", "callAppTrtc")
                
                when (info.type) {
                    CallAppTrtc.CallAppTrtcType.joinRoom.name -> {
                        log("joinRoom====0")
                        if (urlParamMap?.containsKey("roomId") == true) {
                            log("joinRoom====1")
                            if (hasLeave == false) {
                                log("joinRoom====2-1")
                                //这里直接返回成功
                                callBack.invoke(BaseJSBridgeDataT(result = true))
                                //告诉js用户userId
                                val data = NotifyTrtcH5(
                                        type = NotifyTrtcH5.NotifyTrtcH5Type.onRemoteUserEnterRoom.name,
                                        params = NotifyTrtcH5.UserEnterRoom(clientUserId ?: "")
                                )
                                webView?.notifyTrtcH5(data)
                                log("joinRoom====2-2")
                                return
                            }
                            log("joinRoom====3==hasLeave:${hasLeave}")
                            if (hasLeave == true) {
                                log("joinRoom====4-1")
                                //这里直接返回成功
                                callBack.invoke(BaseJSBridgeDataT(result = true))
                                //用户已经离开了，不调notifyTrtcH5，全景那边3秒没收到消息会判定用户已离开
                                log("joinRoom====4-2")
                                return
                            }
                            log("joinRoom====5")
                        }

                        if (autoEnterSuccess == true) {
                            log("joinRoom====5--1")
                            callBack.invoke(BaseJSBridgeDataT(result = true))
                            return
                        } else if (autoEnterSuccess == false) {
                            log("joinRoom====5--2")
                            callBack.invoke(BaseJSBridgeDataT(result = false))
                            return
                        }

                        log("joinRoom====6${Gson().toJson(info.params)}")

                        //加入房间
                        log("joinRoom====7")
                        trtcUtils = TRTCUtils()
                        trtcUtils?.init(
                                context,
                                info.params?.sdkAppId ?: 0,
                                info.params?.userId ?: "",
                                info.params?.roomId ?: 0,
                                info.params?.userSig ?: "",
                                object : TRTCCloudCallBack {
                                    override fun onRemoteUserEnterRoom(userId: String) {
                                        log("===有人进房了：${userId}")
                                        log("joinRoom====7-1")
                                        val data = NotifyTrtcH5(
                                                type = NotifyTrtcH5.NotifyTrtcH5Type.onRemoteUserEnterRoom.name,
                                                params = NotifyTrtcH5.UserEnterRoom(
                                                        userId
                                                )
                                        )
                                        webView?.notifyTrtcH5(data)
                                    }

                                    override fun onRemoteUserLeaveRoom(
                                            userId: String,
                                            reason: Int
                                    ) {
                                        log("===有人离开了：${userId}---$reason")
                                        log("joinRoom====7-2")
                                        val data = NotifyTrtcH5(
                                                type = NotifyTrtcH5.NotifyTrtcH5Type.onRemoteUserLeaveRoom.name,
                                                params = NotifyTrtcH5.UserLeaveRoom(
                                                        userId, reason
                                                )
                                        )
                                        webView?.notifyTrtcH5(data)
                                    }
                                })

                        // todo 这里是要放到获取录音权限成功后操作 -done
                        audioPermissionCallback = object: AudioPermissionCallbackInterface {
                            override fun requestAudioSuccessCb(){
                                trtcUtils?.enterRoom(
                                        object : TRTCEnterResultCallBack {
                                            override fun onEnterRoomSuccess(result: Long) {
                                                log("joinRoom====8-1")
                                                log("===自己进房成功roomId${info.params?.roomId}：耗时${result}ms")
                                                callBack.invoke(BaseJSBridgeDataT(result = true))

                                                Log.d("callAppTrtc", isFromReceive.toString())

                                                if (isFromReceive) {
                                                    //加入房间成功调接口告诉后端设计师已接听
                                                    val map = UrlUtils.formatUrl2Map(url)
                                                    // todo 通知设计师成功接口放到 flutter 层调 -done
                                                    methodChannel!!.invokeMethod("notifyDesignerJoined", "")
                                                    /*model.hasReceived(
                                                            roomId = trtcUtils?.roomId,
                                                            schemeId = map?.get("schemeId")
                                                                    .parseLongOrNull(),
                                                            vrType = map?.get("vrType").parseIntOrNull()
                                                    )*/
                                                }
                                            }

                                            override fun onEnterRoomError(result: Long) {
                                                log("joinRoom====8-2")
                                                log("===自己进房失败：code==${result}")
                                                callBack.invoke(
                                                        BaseJSBridgeDataT(
                                                                code = result.toString(),
                                                                msg = "进入房间失败",
                                                                result = false
                                                        )
                                                )
                                            }

                                        })
                            }
                            override fun requestAudioFailCb(){
                                log("joinRoom====8-3-faile")
                                callBack.invoke(
                                        BaseJSBridgeDataT(
                                                code = "-10000",
                                                result = false,
                                                msg = "录音权限获取失败"
                                        )
                                )
                            }
                        }
                        methodChannel!!.invokeMethod("requestAudioPermission", "requestAudioSuccessCb,requestAudioFailCb")
                        /*PermissionUtils.requestAudio(
                                // todo context 替换 FragmentActivity 失败
                                // this@VRWebActivity,
                                activity as FragmentActivity,
                                object : PermissionUtils.OnPermissionListener() {
                                    override fun success() {
                                        trtcUtils?.enterRoom(
                                                object : TRTCEnterResultCallBack {
                                                    override fun onEnterRoomSuccess(result: Long) {
                                                        log("joinRoom====8-1")
                                                        log("===自己进房成功roomId${info.params?.roomId}：耗时${result}ms")
                                                        callBack.invoke(BaseJSBridgeDataT(result = true))
                                                        if (isFromReceive) {
                                                            //加入房间成功调接口告诉后端设计师已接听
                                                            val map = UrlUtils.formatUrl2Map(url)
                                                            model.hasReceived(
                                                                    roomId = trtcUtils?.roomId,
                                                                    schemeId = map?.get("schemeId")
                                                                            .parseLongOrNull(),
                                                                    vrType = map?.get("vrType").parseIntOrNull()
                                                            )
                                                        }
                                                    }

                                                    override fun onEnterRoomError(result: Long) {
                                                        log("joinRoom====8-2")
                                                        log("===自己进房失败：code==${result}")
                                                        callBack.invoke(
                                                                BaseJSBridgeDataT(
                                                                        code = result.toString(),
                                                                        msg = "进入房间失败",
                                                                        result = false
                                                                )
                                                        )
                                                    }

                                                })
                                    }

                                    override fun failed() {
                                        super.failed()
                                        log("joinRoom====8-3-faile")
                                        callBack.invoke(
                                                BaseJSBridgeDataT(
                                                        code = "-10000",
                                                        result = false,
                                                        msg = "录音权限获取失败"
                                                )
                                        )
                                    }
                                })*/
                    }
                    CallAppTrtc.CallAppTrtcType.leaveRoom.name -> {
                        trtcUtils?.mTRTCCloud?.setListener(
                                object : TRTCCloudListener() {
                                    override fun onExitRoom(p0: Int) {
                                        super.onExitRoom(p0)
                                        Log.d("onExitRoom", p0.toString())
                                        hasLeave = true
                                        callBack.invoke(BaseJSBridgeDataT(result = true))
                                    }
                                }
                        )
                        //离开房间
                        trtcUtils?.exitRoom()
                        // 在 TRTCCloudImplListener 中处理
                        /*hasLeave = true
                        callBack.invoke(BaseJSBridgeDataT(result = true))*/
                    }
                }
            }

            // todo BuildConfig
            // override fun getVersion() = BuildConfig.VERSION_NAME
            override fun getVersion() = "1.2.8"
        })
    }
    
    // 给 flutter 调用
    fun trtcExitRoom() {
        trtcUtils?.exitRoom()
    }

    fun loadUrl() {
        //currentStep  2
        // webView?.loadUrl(url, progressBar) { titles, title, _ ->
        webView?.loadUrl(url, findViewById(R.id.progressBar)) { titles, title, _ ->

            // todo
            // this@VRWebActivity.titles = titles
            this.titles = titles

            if (title.isNotEmpty()) {
                setTitle(title)
            }
        }

        log("url----${url}")
        //currentStep  3
        initShareBtn()
//        showToastDebug("$url")

//       webView.loadUrl("file:///android_asset/rtmp.html");
    }

    /**
     * 调用js，获取分享参数，如果为null，该页面不需要分享
     */
    private fun initShareBtn() {
        webView!!.getH5ShareParams {
            if (it != null) {
                // ivShare.visibility = View.VISIBLE
                findViewById<ImageView>(R.id.ivShare).visibility = View.VISIBLE
                // todo 分享
                /*ivShare.setOnClickListener { _ ->
                    IntentUtils.intentShare(
                            this,
                            it.shareTitle ?: "${getString(R.string.config_app_name)}",
                            it.shareDesc ?: "${getString(R.string.config_app_name)}",
                            it.shareLink ?: "https://www.niuniuda.com"
                    )
                }*/
                print("这里要分享")
            } else {
                // ivShare.visibility = View.GONE
                findViewById<ImageView>(R.id.ivShare).visibility = View.GONE
                // ivShare.setOnClickListener {}
                findViewById<ImageView>(R.id.ivShare).setOnClickListener {}
            }
        }
    }

    // todo onDestroy 生命周期
    /*override fun onDestroy() {
        super.onDestroy()
        EventBusUtils.unRegister(this)
        webView.destroy()
        if (recorderUtil != null) {
            recorderUtil?.destroy()
        }
        //分享小程序下载图片
        downloadShareImage?.dispose()
        trtcDestroy()
    }*/

    @Subscribe
    fun event(event: EventData.ClientHangUpEvent) {
        val roomId = urlParamMap?.get("roomId").parseIntOrNull()
        if (roomId != null && event.roomId == roomId && trtcUtils?.inRoom == true) {
            showToast("业主已挂断")
            finish("")
        }
    }

    @Subscribe
    fun event(eventData: EventData.CloseLast3DRoamWebView) {
        //两个全景页不能重叠，所以先销毁一个，本方法在 IntentUtils topActivity.finish() 调用
        if (url?.contains("/vr.html") == true) {
            finish("")
        }
    }

    // todo 本来这里是 activity 的返回按钮的回调，现在直接定义为了后退函数
    // override fun onBackPressed() {
    fun onBackPressed() {

        Log.d("OnJSBridgeCallBack", "onBackPressed")

        if (trtcUtils?.inRoom == true) {
            // todo 二次弹窗放到 flutter 中 -done
            val map = UrlUtils.formatUrl2Map(url)
            var params = trtcUtils?.roomId.toString() + "," + map?.get("schemeId") + "," + map?.get("vrType").toString()
            finish(params);
            //如果正在音视频
            /*DialogUtils.showDialog(
                    context, "是否退出语音通话", "离开此页面，将结束本次语音互动", "取消", "确认退出",
                    object : DialogUtils.ButtonClickListenerAbstract() {
                        override fun positiveButton() {
                            val map = UrlUtils.formatUrl2Map(url)
                            model.hangUp(
                                    roomId = trtcUtils?.roomId,
                                    schemeId = map?.get("schemeId").parseLongOrNull(),
                                    vrType = map?.get("vrType").parseIntOrNull()
                            ).observe(
                                // todo 这里本来是 activity, 强制改成 context as LifecycleOwner
                                // this@VRWebActivity,
                                context as LifecycleOwner,
                                Observer {
                                    when (it.status) {
                                        Status.LOADING -> {
                                        }
                                        Status.SUCCESS -> {
                                            finish()
                                        }
                                        else -> {
                                        finish()
                                    }
                                    }
                                }
                            )
                        }
                    })*/
        } else {
            finish("");
        }
    }

    // todo 这里本来是 activity 的声明周期，这里直接换成普通方法用-done
    // override fun finish() {
    fun finish(params: String) {
        Log.d("OnJSBridgeCallBack", "finish")
        
        //"https://vr.asman.com.cn/vr.html"
        //如果当前webview是漫游页面的时候，当页面销毁的时候，需要通知群列表当前群的红点删掉
        //TODO  这里的url不带groupId？？？@大力  H5创建群组的时候，需要调native 告知一下，小程序需要H5 postMessage一下
        /*val groupId = UrlUtils.formatUrl2Map(webView?.url)?.get("groupId")
        if (groupId != null) {
            EventBusUtils.post(EventData.IMGroupId(groupId))
        }*/
        
        // todo 下面 activity 的 finish, 变成调用 flutter 后退-done
        methodChannel!!.invokeMethod("onGoBack", params)
        // super.finish()
    }

    private fun setTitle(title: String?) {
        if (title != null && title.contains("http")) { //|| url.contains(title))
            // tvTitle!!.text = ""
            findViewById<TextView>(R.id.tvTitle).text = ""
        } else {
            // tvTitle!!.text = title
            findViewById<TextView>(R.id.tvTitle).text = title
        }
    }

    /**
     * 开始语音录制
     */
    private fun onStartAudioRecord() {
        // todo 拿 activity 的 window
        /*this.window.setFlags(
                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
        )*/
        (context as Activity).window.setFlags(
                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
        )
    }

    /**
     * 结束语音录制
     *
     * @param cancel
     */
    private fun onEndAudioRecord() {
        // window.setFlags(0, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        (context as Activity).window.setFlags(
                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
        )
    }

    fun cancelRecord() {
    }

    //js调用native的getRecord的回调callBack
    private var recordCompletedCallBack: ((ossUrl: String?, isSuccess: Boolean?) -> Unit)? = null

    var clientUserId: String? = null //用户的userId
    var hasLeave: Boolean? = null
    var trtcUtils: TRTCUtils? = null

    var webView: BaseWebView? = null

    //自己是否在房间中
    fun isMySelfInRoom(): Boolean {
        return trtcUtils?.inRoom ?: false
    }

    //获取当前在的房间号
    fun getRoomId(): Int? {
        return trtcUtils?.roomId
    }

    private fun trtcDestroy() {
        trtcUtils?.exitRoom()
    }

    // todo 没有调用这个钩子，直接重写一个在构造函数里调用隐藏按钮
    //隐藏底部虚拟的导航按钮
    /*override fun onWindowFocusChanged(hasFocus: Boolean) {
        super.onWindowFocusChanged(hasFocus)
        if (hasFocus && fullScreen) {
            // todo context -> activity
            *//*window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)*//*
            (context as Activity).window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
        }
    }*/

    fun hiddenBottomButton() {
        /*activity!!.window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)*/
    }





    
    // 下面是父类的方法和成员 ----------------------------------------------------------------------------------------------------------
    // todo 父类 activity 的生命周期函数
    /*override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ActivityUtils.get().addActivity(this)
        log("pagePath：${javaClass.name}")
    }

    override fun onDestroy() {
        super.onDestroy()
        ActivityUtils.get().remove(this)
    }*/
    
    private var dialog: DialogLoadingFragment? = null

    fun showDialogProgress(msg: String) {
        showDialogProgress(msg, false, null)
    }

    fun showDialogProgress(
            msg: String, cancelable: Boolean, onCancelListener: DialogInterface.OnCancelListener?
    ) {
        if (dialog == null) {
            dialog = DialogLoadingFragment.newInstance(msg)
            // todo 这里不是 activity 引用不到 supportFragmentManager 变量
            // dialog?.show(supportFragmentManager)
        } else {
            if (!dialog!!.isResumed) {
                // todo 这里不是 activity 引用不到 supportFragmentManager 变量
                // dialog?.show(supportFragmentManager)
            }
            dialog?.setMsg(msg)
        }
    }

    fun dismissDialog() {
        dialog?.dismiss()
    }
}
